<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>Freetype OpenGL: demo-console.c</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="content"><!-- do not remove this div! -->

<div id="top"><!-- do not remove this div! -->

  
  <div id="titlearea">
    
    <div id="projectname">Freetype OpenGL</div>
    
    
    <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
    
  </div>
  

<!--

<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Freetype OpenGL
   &#160;<span id="projectnumber">0.1</span>
   </div>
   <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
  </td>
  
  
  
   
  
 </tr>
 </tbody>
</table>
</div>
-->


<!-- Generated by Doxygen 1.8.0 -->
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">demo-console.c</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><span class="comment">/* ============================================================================</span>
<span class="comment"> * Freetype GL - A C OpenGL Freetype engine</span>
<span class="comment"> * Platform:    Any</span>
<span class="comment"> * WWW:         http://code.google.com/p/freetype-gl/</span>
<span class="comment"> * ----------------------------------------------------------------------------</span>
<span class="comment"> * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.</span>
<span class="comment"> *</span>
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<span class="comment"> * modification, are permitted provided that the following conditions are met:</span>
<span class="comment"> *</span>
<span class="comment"> *  1. Redistributions of source code must retain the above copyright notice,</span>
<span class="comment"> *     this list of conditions and the following disclaimer.</span>
<span class="comment"> *</span>
<span class="comment"> *  2. Redistributions in binary form must reproduce the above copyright</span>
<span class="comment"> *     notice, this list of conditions and the following disclaimer in the</span>
<span class="comment"> *     documentation and/or other materials provided with the distribution.</span>
<span class="comment"> *</span>
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER &#39;&#39;AS IS&#39;&#39; AND ANY EXPRESS OR</span>
<span class="comment"> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</span>
<span class="comment"> * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO</span>
<span class="comment"> * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,</span>
<span class="comment"> * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span>
<span class="comment"> * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span>
<span class="comment"> * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span>
<span class="comment"> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF</span>
<span class="comment"> * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="comment"> *</span>
<span class="comment"> * The views and conclusions contained in the software and documentation are</span>
<span class="comment"> * those of the authors and should not be interpreted as representing official</span>
<span class="comment"> * policies, either expressed or implied, of Nicolas P. Rougier.</span>
<span class="comment"> * ========================================================================= */</span>
<span class="preprocessor">#include &quot;freetype-gl.h&quot;</span>
<span class="preprocessor">#include &quot;<a class="code" href="vertex-buffer_8h.html">vertex-buffer.h</a>&quot;</span>
<span class="preprocessor">#include &quot;<a class="code" href="markup_8h.html">markup.h</a>&quot;</span>



<span class="comment">// -------------------------------------------------------------- constants ---</span>
<span class="keyword">const</span> <span class="keywordtype">int</span> __SIGNAL_ACTIVATE__     = 0;
<span class="keyword">const</span> <span class="keywordtype">int</span> __SIGNAL_COMPLETE__     = 1;
<span class="keyword">const</span> <span class="keywordtype">int</span> __SIGNAL_HISTORY_NEXT__ = 2;
<span class="keyword">const</span> <span class="keywordtype">int</span> __SIGNAL_HISTORY_PREV__ = 3;
<span class="preprocessor">#define MAX_LINE_LENGTH  511</span>
<span class="preprocessor"></span>

<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_NORMAL      = 0;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_DEFAULT     = 0;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_ERROR       = 1;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_WARNING     = 2;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_OUTPUT      = 3;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_BOLD        = 4;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_ITALIC      = 5;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_BOLD_ITALIC = 6;
<span class="keyword">const</span> <span class="keywordtype">int</span> MARKUP_FAINT       = 7;
<span class="preprocessor">#define   MARKUP_COUNT         8</span>
<span class="preprocessor"></span>

<span class="comment">// ------------------------------------------------------- typedef &amp; struct ---</span>
<span class="keyword">typedef</span> <span class="keyword">struct </span>{
    <span class="keywordtype">float</span> x,y;
    <a name="_a0"></a><a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> color;
} point_t;

<span class="keyword">typedef</span> <span class="keyword">struct </span>{
    <span class="keywordtype">float</span> x, y, z;
    <span class="keywordtype">float</span> s, t;
    <span class="keywordtype">float</span> r, g, b, a;
} vertex_t;

<span class="keyword">struct </span>_console_t {
    <a name="_a1"></a><a class="code" href="structvector__t.html" title="Generic vector structure.">vector_t</a> *     lines;
    <span class="keywordtype">wchar_t</span> *      prompt;
    <span class="keywordtype">wchar_t</span>        killring[MAX_LINE_LENGTH+1];
    <span class="keywordtype">wchar_t</span>        input[MAX_LINE_LENGTH+1];
    <span class="keywordtype">size_t</span>         cursor;
    <a name="_a2"></a><a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a>       markup[MARKUP_COUNT];
    <a name="_a3"></a><a class="code" href="structvertex__buffer__t.html" title="Generic vertex buffer.">vertex_buffer_t</a> * buffer;
    <a name="_a4"></a><a class="code" href="unionvec2.html" title="Tuple of 2 floats.">vec2</a>           pen; 
    void (*handlers[4])( <span class="keyword">struct </span>_console_t *, <span class="keywordtype">wchar_t</span> * );
};
<span class="keyword">typedef</span> <span class="keyword">struct </span>_console_t console_t;


<span class="comment">// ------------------------------------------------------- global variables ---</span>
<span class="keyword">static</span> console_t * console;
<span class="keyword">static</span> <a class="code" href="structvertex__buffer__t.html" title="Generic vertex buffer.">vertex_buffer_t</a> *lines_buffer;


<span class="comment">// ------------------------------------------------------------ console_new ---</span>
console_t *
console_new( <span class="keywordtype">void</span> )
{
    console_t *<span class="keyword">self</span> = (console_t *) malloc( <span class="keyword">sizeof</span>(console_t) );
    <span class="keywordflow">if</span>( !<span class="keyword">self</span> )
    {
        <span class="keywordflow">return</span> <span class="keyword">self</span>;
    }
    <span class="keyword">self</span>-&gt;lines = <a name="a5"></a><a class="code" href="group__vector.html#ga9ab13f896bb29debbbf8175e75751ea5" title="Creates a new empty vector.">vector_new</a>( <span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span> *) );
    <span class="keyword">self</span>-&gt;prompt = (<span class="keywordtype">wchar_t</span> *) wcsdup( L<span class="stringliteral">&quot;&gt;&gt;&gt; &quot;</span> );
    <span class="keyword">self</span>-&gt;cursor = 0;
    <span class="keyword">self</span>-&gt;buffer = <a name="a6"></a><a class="code" href="group__vertex-buffer.html#ga309c1129a1028f251fe6e6c3c1534a42" title="Creates an empty vertex buffer.">vertex_buffer_new</a>( <span class="stringliteral">&quot;v3f:t2f:c4f&quot;</span> );
    <span class="keyword">self</span>-&gt;input[0] = L<span class="charliteral">&#39;\0&#39;</span>;
    <span class="keyword">self</span>-&gt;killring[0] = L<span class="charliteral">&#39;\0&#39;</span>;
    <span class="keyword">self</span>-&gt;handlers[__SIGNAL_ACTIVATE__]     = 0;
    <span class="keyword">self</span>-&gt;handlers[__SIGNAL_COMPLETE__]     = 0;
    <span class="keyword">self</span>-&gt;handlers[__SIGNAL_HISTORY_NEXT__] = 0;
    <span class="keyword">self</span>-&gt;handlers[__SIGNAL_HISTORY_PREV__] = 0;
    <span class="keyword">self</span>-&gt;pen.x = <span class="keyword">self</span>-&gt;pen.y = 0;

    <a name="_a7"></a><a class="code" href="structtexture__atlas__t.html" title="A texture atlas is used to pack several small regions into a single texture.">texture_atlas_t</a> * atlas = <a name="a8"></a><a class="code" href="group__texture-atlas.html#ga7769be70f630e0a8a8b320525a07382d" title="Creates a new empty texture atlas.">texture_atlas_new</a>( 512, 512, 1 );
 
    <a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> white = {{1,1,1,1}};
    <a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> black = {{0,0,0,1}};
    <a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> none = {{0,0,1,0}};
    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> normal = {
        .<a name="a9"></a><a class="code" href="structmarkup__t.html#adcb67782935faf6178ef7afde350ca2a" title="A font family name such as &quot;normal&quot;, &quot;sans&quot;, &quot;serif&quot; or &quot;monospace&quot;.">family</a>  = <span class="stringliteral">&quot;Bistream Vera Sans Mono&quot;</span>,
        .size    = 13.0,
        .bold    = 0,
        .italic  = 0,
        .rise    = 0.0,
        .spacing = 0.0,
        .gamma   = 1.0,
        .foreground_color    = black,
        .background_color    = none,
        .underline           = 0,
        .underline_color     = white,
        .overline            = 0,
        .overline_color      = white,
        .strikethrough       = 0,
        .strikethrough_color = white,
        .font = 0,
    };
    normal.<a name="a10"></a><a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a> = <a name="a11"></a><a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, <span class="stringliteral">&quot;fonts/VeraMono.ttf&quot;</span>, 13 );

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> bold = normal;
    bold.<a name="a12"></a><a class="code" href="structmarkup__t.html#a2f3767ea0ddd6e83154daad12cc4d2d0" title="Whether text is bold.">bold</a> = 1;
    bold.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a> = <a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, <span class="stringliteral">&quot;fonts/VeraMoBd.ttf&quot;</span>, 13 );

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> italic = normal;
    italic.<a name="a13"></a><a class="code" href="structmarkup__t.html#a343eab20b2c5cb225e4b9969bd034642" title="Whether text is italic.">italic</a> = 1;
    bold.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a> = <a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, <span class="stringliteral">&quot;fonts/VeraMoIt.ttf&quot;</span>, 13 );

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> bold_italic = normal;
    bold.<a class="code" href="structmarkup__t.html#a2f3767ea0ddd6e83154daad12cc4d2d0" title="Whether text is bold.">bold</a> = 1;
    italic.<a class="code" href="structmarkup__t.html#a343eab20b2c5cb225e4b9969bd034642" title="Whether text is italic.">italic</a> = 1;
    italic.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a> = <a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, <span class="stringliteral">&quot;fonts/VeraMoBI.ttf&quot;</span>, 13 );

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> faint = normal;
    faint.<a name="a14"></a><a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a name="a15"></a><a class="code" href="unionvec4.html#a1682827e4304b44e6f768d616cdf3899" title="Alias for first component.">r</a> = 0.35;
    faint.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a name="a16"></a><a class="code" href="unionvec4.html#aa626a2728056a1b410fb8e133bdffd05" title="Alias fo second component.">g</a> = 0.35;
    faint.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a name="a17"></a><a class="code" href="unionvec4.html#a62421478df6548c8e5e24d33345e3417" title="Alias fo third component.">b</a> = 0.35;

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> error = normal;
    error.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a1682827e4304b44e6f768d616cdf3899" title="Alias for first component.">r</a> = 1.00;
    error.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#aa626a2728056a1b410fb8e133bdffd05" title="Alias fo second component.">g</a> = 0.00;
    error.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a62421478df6548c8e5e24d33345e3417" title="Alias fo third component.">b</a> = 0.00;

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> warning = normal;
    warning.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a1682827e4304b44e6f768d616cdf3899" title="Alias for first component.">r</a> = 1.00;
    warning.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#aa626a2728056a1b410fb8e133bdffd05" title="Alias fo second component.">g</a> = 0.50;
    warning.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a62421478df6548c8e5e24d33345e3417" title="Alias fo third component.">b</a> = 0.50;

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> output = normal;
    output.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a1682827e4304b44e6f768d616cdf3899" title="Alias for first component.">r</a> = 0.00;
    output.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#aa626a2728056a1b410fb8e133bdffd05" title="Alias fo second component.">g</a> = 0.00;
    output.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a62421478df6548c8e5e24d33345e3417" title="Alias fo third component.">b</a> = 1.00;

    <span class="keyword">self</span>-&gt;markup[MARKUP_NORMAL] = normal;
    <span class="keyword">self</span>-&gt;markup[MARKUP_ERROR] = error;
    <span class="keyword">self</span>-&gt;markup[MARKUP_WARNING] = warning;
    <span class="keyword">self</span>-&gt;markup[MARKUP_OUTPUT] = output;
    <span class="keyword">self</span>-&gt;markup[MARKUP_FAINT] = faint;
    <span class="keyword">self</span>-&gt;markup[MARKUP_BOLD] = bold;
    <span class="keyword">self</span>-&gt;markup[MARKUP_ITALIC] = italic;
    <span class="keyword">self</span>-&gt;markup[MARKUP_BOLD_ITALIC] = bold_italic;

    <span class="keywordflow">return</span> <span class="keyword">self</span>;
}



<span class="comment">// -------------------------------------------------------- console_delete ---</span>
<span class="keywordtype">void</span>
console_delete( console_t *<span class="keyword">self</span> )
{ }



<span class="comment">// ----------------------------------------------------- console_add_glyph ---</span>
<span class="keywordtype">void</span>
console_add_glyph( console_t *<span class="keyword">self</span>,
                   <span class="keywordtype">wchar_t</span> current,
                   <span class="keywordtype">wchar_t</span> previous,
                   <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> *markup )
{
    <a name="_a18"></a><a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> *glyph  = <a name="a19"></a><a class="code" href="group__texture-font.html#ga06e988448ef6e118aa6e273df5892937" title="Request a new glyph from the font.">texture_font_get_glyph</a>( markup-&gt;<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>, current );
    <span class="keywordflow">if</span>( previous != L<span class="charliteral">&#39;\0&#39;</span> )
    {
        <span class="keyword">self</span>-&gt;pen.x += <a name="a20"></a><a class="code" href="group__texture-font.html#ga77d1adb569e7eaa4aaf776dc28415c66" title="Get the kerning between two horizontal glyphs.">texture_glyph_get_kerning</a>( glyph, previous );
    }
    <span class="keywordtype">float</span> r = markup-&gt;<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a1682827e4304b44e6f768d616cdf3899" title="Alias for first component.">r</a>;
    <span class="keywordtype">float</span> g = markup-&gt;<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#aa626a2728056a1b410fb8e133bdffd05" title="Alias fo second component.">g</a>;
    <span class="keywordtype">float</span> b = markup-&gt;<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a class="code" href="unionvec4.html#a62421478df6548c8e5e24d33345e3417" title="Alias fo third component.">b</a>;
    <span class="keywordtype">float</span> a = markup-&gt;<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>.<a name="a21"></a><a class="code" href="unionvec4.html#ac1c847c2cd65c10fd059fceb8e57a5f6" title="Alias fo fourth component.">a</a>;
    <span class="keywordtype">int</span> x0  = <span class="keyword">self</span>-&gt;pen.x + glyph-&gt;<a name="a22"></a><a class="code" href="structtexture__glyph__t.html#a1f267cdba6bd1aff244ff72792ab1a38" title="Glyph&#39;s left bearing expressed in integer pixels.">offset_x</a>;
    <span class="keywordtype">int</span> y0  = <span class="keyword">self</span>-&gt;pen.y + glyph-&gt;<a name="a23"></a><a class="code" href="structtexture__glyph__t.html#aeacd07f592dfa953f26b2e5c1863a814" title="Glyphs&#39;s top bearing expressed in integer pixels.">offset_y</a>;
    <span class="keywordtype">int</span> x1  = x0 + glyph-&gt;<a name="a24"></a><a class="code" href="structtexture__glyph__t.html#a51379921bd46b454fc56b7d28381af03" title="Glyph&#39;s width in pixels.">width</a>;
    <span class="keywordtype">int</span> y1  = y0 - glyph-&gt;<a name="a25"></a><a class="code" href="structtexture__glyph__t.html#a7a0e2fc48006cf6815e5b1e7dae8d386" title="Glyph&#39;s height in pixels.">height</a>;
    <span class="keywordtype">float</span> s0 = glyph-&gt;<a name="a26"></a><a class="code" href="structtexture__glyph__t.html#adcfb6e5a1b583f96c96d87b006667f2b" title="First normalized texture coordinate (x) of top-left corner.">s0</a>;
    <span class="keywordtype">float</span> t0 = glyph-&gt;<a name="a27"></a><a class="code" href="structtexture__glyph__t.html#ab2fec7dd584f5cfaf14c3b8a807d5e70" title="Second normalized texture coordinate (y) of top-left corner.">t0</a>;
    <span class="keywordtype">float</span> s1 = glyph-&gt;<a name="a28"></a><a class="code" href="structtexture__glyph__t.html#a3849b83a8bb51a6fc32ce77b485d9e95" title="First normalized texture coordinate (x) of bottom-right corner.">s1</a>;
    <span class="keywordtype">float</span> t1 = glyph-&gt;<a name="a29"></a><a class="code" href="structtexture__glyph__t.html#aee3ba35a29e1646df9cfaca6c0db3488" title="Second normalized texture coordinate (y) of bottom-right corner.">t1</a>;

    GLuint indices[] = {0,1,2, 0,2,3};
    vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                            { x0,y1,0,  s0,t1,  r,g,b,a },
                            { x1,y1,0,  s1,t1,  r,g,b,a },
                            { x1,y0,0,  s1,t0,  r,g,b,a } };
    <a name="a30"></a><a class="code" href="group__vertex-buffer.html#ga6cefde8ec247bcf71ff62409b2aa056a" title="Append a new item to the collection.">vertex_buffer_push_back</a>( self-&gt;buffer, vertices, 4, indices, 6 );
    
    <span class="keyword">self</span>-&gt;pen.x += glyph-&gt;<a name="a31"></a><a class="code" href="structtexture__glyph__t.html#aba3ece1130e9d96562a5c2ec3e60da4c" title="For horizontal text layouts, this is the horizontal distance (in fractional pixels) used to increment...">advance_x</a>;
    <span class="keyword">self</span>-&gt;pen.y += glyph-&gt;<a name="a32"></a><a class="code" href="structtexture__glyph__t.html#a1e13821e9ea8332f828ebb95aeefac06" title="For vertical text layouts, this is the vertical distance (in fractional pixels) used to increment the...">advance_y</a>;
}



<span class="comment">// -------------------------------------------------------- console_render ---</span>
<span class="keywordtype">void</span>
console_render( console_t *<span class="keyword">self</span> )
{
    <span class="keywordtype">int</span> viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );

    <span class="keywordtype">size_t</span> i, index;
    <span class="keyword">self</span>-&gt;pen.x = 0;
    <span class="keyword">self</span>-&gt;pen.y = viewport[3];
    <a name="a33"></a><a class="code" href="group__vertex-buffer.html#ga5a1c907e3e66b12be0c142e6d03acdaf" title="Clear all items.">vertex_buffer_clear</a>( console-&gt;buffer );

    <span class="keywordtype">int</span> cursor_x = <span class="keyword">self</span>-&gt;pen.x;
    <span class="keywordtype">int</span> cursor_y = <span class="keyword">self</span>-&gt;pen.y;

    <a class="code" href="structmarkup__t.html" title="Simple structure that describes text properties.">markup_t</a> markup;

    <span class="comment">// console_t buffer</span>
    markup = <span class="keyword">self</span>-&gt;markup[MARKUP_FAINT];
    <span class="keyword">self</span>-&gt;pen.y -= markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a name="a34"></a><a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a>;

    <span class="keywordflow">for</span>( i=0; i&lt;<span class="keyword">self</span>-&gt;lines-&gt;size; ++i )
    {
        <span class="keywordtype">wchar_t</span> *text = * (<span class="keywordtype">wchar_t</span> **) <a name="a35"></a><a class="code" href="group__vector.html#ga6ed3fefa82526009ff0763191dcd9a93" title="Returns a pointer to the item located at specified index.">vector_get</a>( self-&gt;lines, i ) ;
        <span class="keywordflow">if</span>( wcslen(text) &gt; 0 )
        {
            console_add_glyph( console, text[0], L<span class="charliteral">&#39;\0&#39;</span>, &amp;markup );
            <span class="keywordflow">for</span>( index=1; index &lt; wcslen(text)-1; ++index )
            {
                console_add_glyph( console, text[index], text[index-1], &amp;markup );
            }
        }
        <span class="keyword">self</span>-&gt;pen.y -= markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a> - markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a name="a36"></a><a class="code" href="structtexture__font__t.html#af40d45f0616a523d97206e6e0e72f421" title="This field is the distance that must be placed between two lines of text.">linegap</a>;
        <span class="keyword">self</span>-&gt;pen.x = 0;
        cursor_x = <span class="keyword">self</span>-&gt;pen.x;
        cursor_y = <span class="keyword">self</span>-&gt;pen.y;
    }

    <span class="comment">// Prompt</span>
    markup = <span class="keyword">self</span>-&gt;markup[MARKUP_BOLD];
    <span class="keywordflow">if</span>( wcslen( self-&gt;prompt ) &gt; 0 )
    {
        console_add_glyph( console, self-&gt;prompt[0], L<span class="charliteral">&#39;\0&#39;</span>, &amp;markup );
        <span class="keywordflow">for</span>( index=1; index &lt; wcslen(self-&gt;prompt); ++index )
        {
            console_add_glyph( console, self-&gt;prompt[index], self-&gt;prompt[index-1], &amp;markup );
        }
    }
    cursor_x = (int) self-&gt;pen.x;

    <span class="comment">// Input</span>
    markup = self-&gt;markup[MARKUP_NORMAL];
    <span class="keywordflow">if</span>( wcslen(self-&gt;input) &gt; 0 )
    {
        console_add_glyph( console, self-&gt;input[0], L<span class="charliteral">&#39;\0&#39;</span>, &amp;markup );
        <span class="keywordflow">if</span>( self-&gt;cursor &gt; 0)
        {
            cursor_x = (int) self-&gt;pen.x;
        }
        <span class="keywordflow">for</span>( index=1; index &lt; wcslen(self-&gt;input); ++index )
        {
            console_add_glyph( console, self-&gt;input[index], self-&gt;input[index-1], &amp;markup );
            <span class="keywordflow">if</span>( index &lt; self-&gt;cursor )
            {
                cursor_x = (int) self-&gt;pen.x;
            }
        }
    }

    <span class="comment">// Cursor</span>
    <a class="code" href="group__vertex-buffer.html#ga5a1c907e3e66b12be0c142e6d03acdaf" title="Clear all items.">vertex_buffer_clear</a>( lines_buffer );
    <span class="keywordtype">float</span> x  = cursor_x+1;
    <span class="keywordtype">float</span> y1 = cursor_y+markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a name="a37"></a><a class="code" href="structtexture__font__t.html#af310fa623576a8436bff9354f9a5c048" title="The descender is the vertical distance from the horizontal baseline to the lowest &#39;character&#39; coordin...">descender</a>;
    <span class="keywordtype">float</span> y2 = y1 + markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a> - markup.<a class="code" href="structmarkup__t.html#a5c61d3d8f7da003b885a413780240318" title="Pointer on the corresponding font (family/size/bold/italic)">font</a>-&gt;<a class="code" href="structtexture__font__t.html#af40d45f0616a523d97206e6e0e72f421" title="This field is the distance that must be placed between two lines of text.">linegap</a>;
    point_t vertices[2] ={ {x, y1, markup.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>},
                           {x, y2, markup.<a class="code" href="structmarkup__t.html#a04c930fd29432569aee47e56b59e3d79" title="Text color.">foreground_color</a>} };
    GLuint indices[] = {0,1};
    <a class="code" href="group__vertex-buffer.html#ga6cefde8ec247bcf71ff62409b2aa056a" title="Append a new item to the collection.">vertex_buffer_push_back</a>( lines_buffer, vertices, 2, indices, 2 );

    glColor4f(1,1,1,1);
    glEnable( GL_TEXTURE_2D );
    <a name="a38"></a><a class="code" href="group__vertex-buffer.html#ga48df5bafd9315aabfb7f14bedb778c16" title="Render vertex buffer.">vertex_buffer_render</a>( console-&gt;buffer, GL_TRIANGLES, <span class="stringliteral">&quot;vtc&quot;</span> );
    glDisable( GL_TEXTURE_2D );
    <a class="code" href="group__vertex-buffer.html#ga48df5bafd9315aabfb7f14bedb778c16" title="Render vertex buffer.">vertex_buffer_render</a>( lines_buffer, GL_LINES, <span class="stringliteral">&quot;vc&quot;</span> );
}



<span class="comment">// ------------------------------------------------------- console_connect ---</span>
<span class="keywordtype">void</span>
console_connect( console_t *<span class="keyword">self</span>,
                  <span class="keyword">const</span> <span class="keywordtype">char</span> *signal,
                  <span class="keywordtype">void</span> (*handler)(console_t *, <span class="keywordtype">wchar_t</span> *))
{
    <span class="keywordflow">if</span>( strcmp( signal,<span class="stringliteral">&quot;activate&quot;</span> ) == 0 )
    {
        <span class="keyword">self</span>-&gt;handlers[__SIGNAL_ACTIVATE__] = handler;
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( signal,<span class="stringliteral">&quot;complete&quot;</span> ) == 0 )
    {
        <span class="keyword">self</span>-&gt;handlers[__SIGNAL_COMPLETE__] = handler;
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( signal,<span class="stringliteral">&quot;history-next&quot;</span> ) == 0 )
    {
        <span class="keyword">self</span>-&gt;handlers[__SIGNAL_HISTORY_NEXT__] = handler;
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( signal,<span class="stringliteral">&quot;history-prev&quot;</span> ) == 0 )
    {
        <span class="keyword">self</span>-&gt;handlers[__SIGNAL_HISTORY_PREV__] = handler;
    }
}



<span class="comment">// --------------------------------------------------------- console_print ---</span>
<span class="keywordtype">void</span>
console_print( console_t *<span class="keyword">self</span>, <span class="keywordtype">wchar_t</span> *text )
{
    <span class="comment">// Make sure there is at least one line</span>
    <span class="keywordflow">if</span>( self-&gt;lines-&gt;size == 0 )
    {
        <span class="keywordtype">wchar_t</span> *line = wcsdup( L<span class="stringliteral">&quot;&quot;</span> );
        <a name="a39"></a><a class="code" href="group__vector.html#ga0934c3049233d3688b7fa74e23536bbf" title="Appends given item to the end of the vector.">vector_push_back</a>( self-&gt;lines, &amp;line );
    }

    <span class="comment">// Make sure last line does not end with &#39;\n&#39;</span>
    <span class="keywordtype">wchar_t</span> *last_line = *(<span class="keywordtype">wchar_t</span> **) <a class="code" href="group__vector.html#ga6ed3fefa82526009ff0763191dcd9a93" title="Returns a pointer to the item located at specified index.">vector_get</a>( self-&gt;lines, self-&gt;lines-&gt;size-1 ) ;
    <span class="keywordflow">if</span>( wcslen( last_line ) != 0 )
    {
        <span class="keywordflow">if</span>( last_line[wcslen( last_line ) - 1] == L<span class="charliteral">&#39;\n&#39;</span> )
        {
            <span class="keywordtype">wchar_t</span> *line = wcsdup( L<span class="stringliteral">&quot;&quot;</span> );
            <a class="code" href="group__vector.html#ga0934c3049233d3688b7fa74e23536bbf" title="Appends given item to the end of the vector.">vector_push_back</a>( self-&gt;lines, &amp;line );
        }
    }
    last_line = *(<span class="keywordtype">wchar_t</span> **) <a class="code" href="group__vector.html#ga6ed3fefa82526009ff0763191dcd9a93" title="Returns a pointer to the item located at specified index.">vector_get</a>( self-&gt;lines, self-&gt;lines-&gt;size-1 ) ;

    <span class="keywordtype">wchar_t</span> *start = text;
    <span class="keywordtype">wchar_t</span> *end   = wcschr(start, L<span class="charliteral">&#39;\n&#39;</span>);
    <span class="keywordtype">size_t</span> len = wcslen( last_line );
    <span class="keywordflow">if</span>( end != NULL)
    {
        <span class="keywordtype">wchar_t</span> *line = (<span class="keywordtype">wchar_t</span> *) malloc( (len + end - start + 2)*<span class="keyword">sizeof</span>( wchar_t ) );
        wcpncpy( line, last_line, len );
        wcpncpy( line + len, text, end-start+1 );

        line[len+end-start+1] = L<span class="charliteral">&#39;\0&#39;</span>;

        <a name="a40"></a><a class="code" href="group__vector.html#ga50c566682c6ec48ef8f7f4224c112d03" title="Replace an item.">vector_set</a>( self-&gt;lines, self-&gt;lines-&gt;size-1, &amp;line );
        free( last_line );
        <span class="keywordflow">if</span>( (end-start)  &lt; (wcslen( text )-1) )
        {
            console_print(<span class="keyword">self</span>, end+1 );
        }
        <span class="keywordflow">return</span>;
    }
    <span class="keywordflow">else</span>
    {
        <span class="keywordtype">wchar_t</span> *line = (<span class="keywordtype">wchar_t</span> *) malloc( (len + wcslen(text) + 1) * <span class="keyword">sizeof</span>( wchar_t ) );
        wcpncpy( line, last_line, len );
        wcpcpy( line + len, text );
        <a class="code" href="group__vector.html#ga50c566682c6ec48ef8f7f4224c112d03" title="Replace an item.">vector_set</a>( self-&gt;lines, self-&gt;lines-&gt;size-1, &amp;line );
        free( last_line );
        <span class="keywordflow">return</span>;
    }
}



<span class="comment">// ------------------------------------------------------- console_process ---</span>
<span class="keywordtype">void</span>
console_process( console_t *<span class="keyword">self</span>,
                  <span class="keyword">const</span> <span class="keywordtype">char</span> *action,
                  <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key )
{
    <span class="keywordtype">size_t</span> len = wcslen(self-&gt;input);

    <span class="keywordflow">if</span>( strcmp(action, <span class="stringliteral">&quot;type&quot;</span>) == 0 )
    {
        <span class="keywordflow">if</span>( len &lt; MAX_LINE_LENGTH )
        {
            memmove( self-&gt;input + self-&gt;cursor+1,
                     self-&gt;input + self-&gt;cursor, 
                     (len - self-&gt;cursor+1)*<span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span>) );
            <span class="keyword">self</span>-&gt;input[<span class="keyword">self</span>-&gt;cursor] = (wchar_t) key;
            <span class="keyword">self</span>-&gt;cursor++;
        }
        <span class="keywordflow">else</span>
        {
            fprintf( stderr, <span class="stringliteral">&quot;Input buffer is full\n&quot;</span> );
        }
    }
    <span class="keywordflow">else</span>
    {
        <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;enter&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( console-&gt;handlers[__SIGNAL_ACTIVATE__] )
            {
                (*console-&gt;handlers[__SIGNAL_ACTIVATE__])(console, console-&gt;input);
            }
            console_print( <span class="keyword">self</span>, self-&gt;prompt );
            console_print( <span class="keyword">self</span>, self-&gt;input );
            console_print( <span class="keyword">self</span>, L<span class="stringliteral">&quot;\n&quot;</span> );
            <span class="keyword">self</span>-&gt;input[0] = L<span class="charliteral">&#39;\0&#39;</span>;
            <span class="keyword">self</span>-&gt;cursor = 0;
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;right&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( self-&gt;cursor &lt; wcslen(self-&gt;input) )
            {
                <span class="keyword">self</span>-&gt;cursor += 1;
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;left&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( self-&gt;cursor &gt; 0 )
            {
                <span class="keyword">self</span>-&gt;cursor -= 1;
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;delete&quot;</span> ) == 0 )
        {
            memmove( self-&gt;input + self-&gt;cursor,
                     self-&gt;input + self-&gt;cursor+1, 
                     (len - self-&gt;cursor)*<span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span>) );
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;backspace&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( self-&gt;cursor &gt; 0 )
            {
                memmove( self-&gt;input + self-&gt;cursor-1,
                         self-&gt;input + self-&gt;cursor, 
                         (len - self-&gt;cursor+1)*<span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span>) );
                <span class="keyword">self</span>-&gt;cursor--;
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;kill&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( self-&gt;cursor &lt; len )
            {
                wcpcpy(self-&gt;killring, self-&gt;input + self-&gt;cursor );
                <span class="keyword">self</span>-&gt;input[<span class="keyword">self</span>-&gt;cursor] = L<span class="charliteral">&#39;\0&#39;</span>;
                fwprintf(stderr, L<span class="stringliteral">&quot;Kill ring: %ls\n&quot;</span>, self-&gt;killring);
            }
            
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;yank&quot;</span> ) == 0 )
        {
            <span class="keywordtype">size_t</span> l = wcslen(self-&gt;killring);
            <span class="keywordflow">if</span>( (len + l) &lt; MAX_LINE_LENGTH )
            {
                memmove( self-&gt;input + self-&gt;cursor + l,
                         self-&gt;input + self-&gt;cursor, 
                         (len - self-&gt;cursor)*<span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span>) );
                memcpy( self-&gt;input + self-&gt;cursor,
                        self-&gt;killring, l*<span class="keyword">sizeof</span>(<span class="keywordtype">wchar_t</span>));
                <span class="keyword">self</span>-&gt;cursor += l;
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;home&quot;</span> ) == 0 )
        {
            <span class="keyword">self</span>-&gt;cursor = 0;
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;end&quot;</span> ) == 0 )
        {
            <span class="keyword">self</span>-&gt;cursor = wcslen( self-&gt;input );
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;clear&quot;</span> ) == 0 )
        {
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;history-prev&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( console-&gt;handlers[__SIGNAL_HISTORY_PREV__] )
            {
                (*console-&gt;handlers[__SIGNAL_HISTORY_PREV__])(console, console-&gt;input);
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;history-next&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( console-&gt;handlers[__SIGNAL_HISTORY_NEXT__] )
            {
                (*console-&gt;handlers[__SIGNAL_HISTORY_NEXT__])(console, console-&gt;input);
            }
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>( strcmp( action, <span class="stringliteral">&quot;complete&quot;</span> ) == 0 )
        {
            <span class="keywordflow">if</span>( console-&gt;handlers[__SIGNAL_COMPLETE__] )
            {
                (*console-&gt;handlers[__SIGNAL_COMPLETE__])(console, console-&gt;input);
            }
        }
    }
}



<span class="comment">// ----------------------------------------------------------- on_key_press ---</span>
<span class="keywordtype">void</span>
on_key_press ( <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key, <span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y )
{
    <span class="comment">// fprintf( stderr, &quot;key: %d\n&quot;, key);</span>
    <span class="keywordflow">if</span> (key == 1)
    {
        console_process( console, <span class="stringliteral">&quot;home&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 4)
    { 
        console_process( console, <span class="stringliteral">&quot;delete&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 5)
    { 
        console_process( console, <span class="stringliteral">&quot;end&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 8)
    { 
        console_process( console, <span class="stringliteral">&quot;backspace&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 9)
    {
        console_process( console, <span class="stringliteral">&quot;complete&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 11)
    {
        console_process( console, <span class="stringliteral">&quot;kill&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 12)
    {
        console_process( console, <span class="stringliteral">&quot;clear&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 13)
    {
        console_process( console, <span class="stringliteral">&quot;enter&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 25)
    {
        console_process( console, <span class="stringliteral">&quot;yank&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 27)
    {
        console_process( console, <span class="stringliteral">&quot;escape&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span> (key == 127)
    {
        console_process( console, <span class="stringliteral">&quot;backspace&quot;</span>, 0 );
    }
    <span class="keywordflow">else</span> <span class="keywordflow">if</span>( key &gt; 31)
    {
        console_process( console, <span class="stringliteral">&quot;type&quot;</span>, key );
    }
    glutPostRedisplay();
}



<span class="comment">// --------------------------------------------------- on_special_key_press ---</span>
<span class="keywordtype">void</span>
on_special_key_press( <span class="keywordtype">int</span> key, <span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y )
{
    <span class="keywordflow">switch</span> (key)
    {
    <span class="keywordflow">case</span> GLUT_KEY_UP:
        console_process( console, <span class="stringliteral">&quot;history-prev&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> GLUT_KEY_DOWN:
        console_process( console, <span class="stringliteral">&quot;history-next&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> GLUT_KEY_LEFT:
        console_process( console,  <span class="stringliteral">&quot;left&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> GLUT_KEY_RIGHT:
        console_process( console, <span class="stringliteral">&quot;right&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> GLUT_KEY_HOME:
        console_process( console, <span class="stringliteral">&quot;home&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> GLUT_KEY_END:
        console_process( console, <span class="stringliteral">&quot;end&quot;</span>, 0 );
        <span class="keywordflow">break</span>;
    <span class="keywordflow">default</span>:
        <span class="keywordflow">break</span>;
    }
    glutPostRedisplay();
}



<span class="comment">// ------------------------------------------------------------- on_display ---</span>
<span class="keywordtype">void</span> on_display (<span class="keywordtype">void</span>) {
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    console_render( console );
    glutSwapBuffers();
}



<span class="comment">// ------------------------------------------------------------- on_reshape ---</span>
<span class="keywordtype">void</span> on_reshape (<span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, 0, height, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}



<span class="comment">// ---------------------------------------------------------------- on_init ---</span>
<span class="keywordtype">void</span> on_init( <span class="keywordtype">void</span> )
{
}


<span class="comment">// ----------------------------------------------------------------------------</span>
<span class="keywordtype">void</span> console_activate (console_t *<span class="keyword">self</span>, <span class="keywordtype">wchar_t</span> * input)
{
    <span class="comment">//console_print( self, L&quot;Activate callback\n&quot; );</span>
    fwprintf( stderr, L<span class="stringliteral">&quot;Activate callback : %ls\n&quot;</span>, input );
}
<span class="keywordtype">void</span> console_complete (console_t *<span class="keyword">self</span>, <span class="keywordtype">wchar_t</span> *input)
{
    <span class="comment">// console_print( self, L&quot;Complete callback\n&quot; );</span>
    fwprintf( stderr, L<span class="stringliteral">&quot;Complete callback : %ls\n&quot;</span>, input );
}
<span class="keywordtype">void</span> console_history_prev (console_t *<span class="keyword">self</span>, <span class="keywordtype">wchar_t</span> *input)
{
    <span class="comment">// console_print( self, L&quot;History prev callback\n&quot; );</span>
    fwprintf( stderr, L<span class="stringliteral">&quot;History prev callback : %ls\n&quot;</span>, input );
}
<span class="keywordtype">void</span> console_history_next (console_t *<span class="keyword">self</span>, <span class="keywordtype">wchar_t</span> *input)
{
    <span class="comment">// console_print( self, L&quot;History next callback\n&quot; );</span>
    fwprintf( stderr, L<span class="stringliteral">&quot;History next callback : %ls\n&quot;</span>, input );
}


<span class="keywordtype">int</span>
main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv )
{
    glutInit( &amp;argc, argv );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( argv[0] );
    glutReshapeFunc( on_reshape );
    glutDisplayFunc( on_display );
    glutKeyboardFunc( on_key_press );
    glutSpecialFunc( on_special_key_press );
    glutReshapeWindow( 600,400 );

    lines_buffer = <a class="code" href="group__vertex-buffer.html#ga309c1129a1028f251fe6e6c3c1534a42" title="Creates an empty vertex buffer.">vertex_buffer_new</a>( <span class="stringliteral">&quot;v2f:c4f&quot;</span> ); 
    console = console_new();
    console_print( console,
                   L<span class="stringliteral">&quot;OpenGL Freetype console\n&quot;</span>
                   L<span class="stringliteral">&quot;Copyright 2011 Nicolas P. Rougier. All rights reserved.\n \n&quot;</span> );
    console_connect( console, <span class="stringliteral">&quot;activate&quot;</span>,     console_activate );
    console_connect( console, <span class="stringliteral">&quot;complete&quot;</span>,     console_complete );
    console_connect( console, <span class="stringliteral">&quot;history-prev&quot;</span>, console_history_prev );
    console_connect( console, <span class="stringliteral">&quot;history-next&quot;</span>, console_history_next );

    glClearColor( 1.00, 1.00, 1.00, 1.00 );
    glDisable( GL_DEPTH_TEST ); 
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_BLEND );

    glutMainLoop();

    <span class="keywordflow">return</span> 0;
}
</pre></div> </div><!-- contents -->
</div>
</body>
</html>
